"""
记账相关的 Pydantic 模型
"""

from datetime import date, datetime

from pydantic import BaseModel, Field, field_validator

from src.models.accounting_model import AccountType, TransactionType


# 分类相关的 Schema
class CategoryBase(BaseModel):
    """分类基础模型"""

    name: str = Field(..., min_length=1, max_length=50, description="分类名称")
    parent_id: int | None = Field(None, description="父分类ID")
    icon: str | None = Field(None, max_length=50, description="图标标识")
    color: str | None = Field(None, max_length=20, description="颜色代码")
    sort_order: int = Field(0, description="排序顺序")


class CategoryCreate(CategoryBase):
    """创建分类模型"""

    pass


class CategoryUpdate(BaseModel):
    """更新分类模型"""

    # name字段不允许更新,因为与交易记录有关联关系
    parent_id: int | None = Field(None, description="父分类ID")
    icon: str | None = Field(None, max_length=50, description="图标标识")
    color: str | None = Field(None, max_length=20, description="颜色代码")
    sort_order: int | None = Field(None, description="排序顺序")


class CategoryResponse(CategoryBase):
    """分类响应模型"""

    id: int
    family_id: int
    is_system: bool
    created_at: datetime
    updated_at: datetime | None = None
    family_name: str | None = None
    parent_name: str | None = None

    model_config = {"from_attributes": True}


class CategoryWithChildren(CategoryResponse):
    """包含子分类的分类响应模型"""

    children: list["CategoryResponse"] = []


# 账户相关的 Schema
class AccountBase(BaseModel):
    """账户基础模型"""

    name: str = Field(..., min_length=1, max_length=50, description="账户名称")
    account_type: AccountType = Field(..., description="账户类型")
    initial_balance: float = Field(0.00, ge=0, description="初始余额")
    icon: str | None = Field(None, max_length=50, description="图标标识")
    color: str | None = Field(None, max_length=20, description="颜色代码")
    description: str | None = Field(None, description="账户描述")


class AccountCreate(AccountBase):
    """创建账户模型"""

    pass


class AccountUpdate(BaseModel):
    """更新账户模型"""

    # name字段不允许更新,因为与交易记录有关联关系
    account_type: AccountType | None = Field(None, description="账户类型")
    icon: str | None = Field(None, max_length=50, description="图标标识")
    color: str | None = Field(None, max_length=20, description="颜色代码")
    description: str | None = Field(None, description="账户描述")
    is_active: bool | None = Field(None, description="是否启用")


class AccountResponse(AccountBase):
    """账户响应模型"""

    id: int
    family_id: int
    balance: float
    is_active: bool
    created_at: datetime
    updated_at: datetime | None = None
    family_name: str | None = None

    model_config = {"from_attributes": True}


# 项目相关的 Schema
class ProjectBase(BaseModel):
    """项目基础模型"""

    name: str = Field(..., min_length=1, max_length=100, description="项目名称")
    description: str | None = Field(None, description="项目描述")
    start_date: date | None = Field(None, description="开始日期")
    end_date: date | None = Field(None, description="结束日期")
    budget: float = Field(0, ge=0, description="预算金额")
    color: str | None = Field(None, max_length=20, description="颜色代码")


class ProjectCreate(ProjectBase):
    """创建项目模型"""

    pass


class ProjectUpdate(BaseModel):
    """更新项目模型"""

    # name字段不允许更新,因为与交易记录有关联关系
    description: str | None = Field(None, description="项目描述")
    start_date: date | None = Field(None, description="开始日期")
    end_date: date | None = Field(None, description="结束日期")
    budget: float = Field(0.00, ge=0, description="预算金额")
    color: str | None = Field(None, max_length=20, description="颜色代码")
    is_active: bool | None = Field(None, description="是否启用")


class ProjectResponse(ProjectBase):
    """项目响应模型"""

    id: int
    family_id: int
    is_active: bool
    created_at: datetime
    updated_at: datetime | None = None
    family_name: str | None = None

    model_config = {"from_attributes": True}


# 交易记录相关的 Schema
class TransactionBase(BaseModel):
    """交易记录基础模型"""

    transaction_type: TransactionType = Field(..., description="交易类型")
    amount: float = Field(gt=0, description="交易金额")
    category_id: int | None = Field(None, description="分类ID")
    account_id: int = Field(..., description="账户ID")
    to_account_id: int | None = Field(None, description="目标账户ID(转账时使用)")
    project_id: int | None = Field(None, description="项目ID")
    member_id: int | None = Field(None, description="家庭成员ID")
    transaction_date: datetime = Field(..., description="交易日期")
    description: str | None = Field(None, description="交易描述")
    is_recurring: bool = Field(False, description="是否定期交易")
    recurring_pattern: str | None = Field(
        None, max_length=50, description="定期模式"
    )
    tags: str | None = Field(None, max_length=500, description="标签,逗号分隔")
    receipt_image: str | None = Field(
        None, max_length=255, description="收据图片URL"
    )

    @field_validator("to_account_id")
    def validate_to_account_id(cls, v, info):
        """验证目标账户ID"""
        data = info.data
        if (
            "transaction_type" in data
            and data["transaction_type"] == TransactionType.TRANSFER
        ):
            if v is None:
                raise ValueError("转账交易必须指定目标账户")
            if v == data.get("account_id"):
                raise ValueError("目标账户不能与源账户相同")
        elif v is not None:
            raise ValueError("只有转账交易可以指定目标账户")
        return v

    @field_validator("category_id")
    def validate_category_id(cls, v, info):
        """验证分类ID"""
        data = info.data
        if (
            "transaction_type" in data
            and data["transaction_type"] == TransactionType.TRANSFER
        ):
            if v is not None:
                raise ValueError("转账交易不能指定分类")
        return v


class TransactionCreate(TransactionBase):
    """创建交易记录模型"""

    pass


class TransactionUpdate(BaseModel):
    """更新交易记录模型"""

    transaction_type: TransactionType | None = Field(None, description="交易类型")
    amount: float | None = Field(None, gt=0, description="交易金额")
    category_id: int | None = Field(None, description="分类ID")
    account_id: int | None = Field(None, description="账户ID")
    to_account_id: int | None = Field(None, description="目标账户ID(转账时使用)")
    project_id: int | None = Field(None, description="项目ID")
    member_id: int | None = Field(None, description="家庭成员ID")
    transaction_date: datetime | None = Field(None, description="交易日期")
    description: str | None = Field(None, description="交易描述")
    is_recurring: bool | None = Field(None, description="是否定期交易")
    recurring_pattern: str | None = Field(
        None, max_length=50, description="定期模式"
    )
    tags: str | None = Field(None, max_length=500, description="标签,逗号分隔")
    receipt_image: str | None = Field(
        None, max_length=255, description="收据图片URL"
    )


class TransactionResponse(TransactionBase):
    """交易记录响应模型"""

    id: int
    family_id: int
    is_deleted: bool
    created_at: datetime
    updated_at: datetime | None = None
    family_name: str | None = None
    category_name: str | None = None
    account_name: str | None = None
    to_account_name: str | None = None
    project_name: str | None = None
    member_name: str | None = None

    model_config = {"from_attributes": True}


class TransactionList(BaseModel):
    """交易记录列表响应模型"""

    transactions: list[TransactionResponse]
    total: int
    skip: int
    limit: int


# 统计相关的 Schema
class TransactionSummary(BaseModel):
    """交易统计摘要"""

    total_income: float
    total_expense: float
    total_transfer: float
    net_income: float
    transaction_count: int


class CategorySummary(BaseModel):
    """分类统计"""

    category_id: int
    category_name: str
    total_amount: float
    transaction_count: int


class AccountSummary(BaseModel):
    """账户统计"""

    account_id: int
    account_name: str
    balance: float
    income_amount: float
    expense_amount: float
    transaction_count: int


class ProjectSummary(BaseModel):
    """项目统计"""

    project_id: int
    project_name: str
    budget: float
    expense_amount: float
    transaction_count: int
    remaining_budget: float = 0


# 批量操作 Schema
class BatchTransactionCreate(BaseModel):
    """批量创建交易记录"""

    transactions: list[TransactionCreate]


class BatchCategoryCreate(BaseModel):
    """批量创建分类"""

    categories: list[CategoryCreate]


# 更新以解决循环引用问题
CategoryWithChildren.model_rebuild()
